package com.ray.service;

import com.google.appengine.api.images.ImagesServicePb.ImagesServiceTransform;
import com.google.appengine.api.search.query.ExpressionParser.name_return;
import com.mchange.util.AssertException;
import com.ray.bean.DatatablesViewPageBean;
import com.ray.bean.DutyBean;
import com.ray.bean.EnergyBean;
import com.ray.bean.EnergyBean.EnergyWorkShop;
import com.ray.bean.ProductionExceptionBean;
import com.ray.bean.WorkEnergyConsumptionBean;
import com.ray.bean.WorkEnergyConsumptionBean.LossBean;
import com.ray.exception.ServiceException;
import com.ray.mapper.EnergyMapper;
import com.ray.mapper.MachineMapper;
import com.ray.util.ReturnStringUtil;
import com.ray.util.StringUtil;
import com.ray.util.TimeAndUnix;
import com.ray.util.WeiXinUtil;
import com.ray.util.redis.RedisCache;
import com.ray.util.redis.RedisKey;

import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class EnergyService {
	@Autowired
	EnergyMapper energyMapper;
	@Autowired
	WorkshopService workshopService;
	@Autowired
	MaterService materService;
	
	public static String url="";
	public static String mianUrl  = "jdbc:sqlserver://115.159.224.19:12580;DatabaseName=SHINEHAO";
	
	//获取所有电表
	public List<EnergyBean> getAllElectricEnergy(Map map){
		List<EnergyBean> energys = energyMapper.getAllElectricEnergy(map);
		return energys;
	}

    //获取所有气表
    public List<EnergyBean> getAllFlowEnergy(Map map) {
        List<EnergyBean> energys = energyMapper.getAllFlowEnergy(map);
        return energys;
    }
	
	/**
	 * 修改占用状态
	 * @param state(状态)
	 * @param (id)
	 * @param map
	 */
	public int updateState(Map map) {
		int x=energyMapper.updateState(map);
		return x;
	}

	/**
	 * According to the input id and status update Energy
	 * @param id The Energy whose Energy id is equal to this id will be updated
	 * @param status this status will update to Energy
	 */
	public void freeOrUseEnergy(String id, int status) {
		if (id != null && !"".equals(id)) {
			Map<String, Object> paramMap = new HashMap<>(2);
			paramMap.put("id", id);
			// 修改表占用状态
			paramMap.put("state", status);
			// 原表释放
			updateState(paramMap);
		}
	}
	//获取电表水表
	public EnergyBean getEnergy(Map map) {
		return energyMapper.getEnergy(map);
	}

	//获取所有电表水表气表
	public DatatablesViewPageBean<EnergyBean> getAllEnergy(Map map) throws ParseException {
		// TODO Auto-generated method stub 
		DatatablesViewPageBean<EnergyBean> dbvpb = new DatatablesViewPageBean<EnergyBean>();
		int total = energyMapper.getAllEnergyCount(map);
		List<EnergyBean> energyList = energyMapper.getAllEnergyDate(map);
		dbvpb.setiTotalRecords(total);
		dbvpb.setiTotalDisplayRecords(total);
		for(EnergyBean equipment:energyList) {
			equipment.setCollectTime(TimeAndUnix.timeToHaoMiao(equipment.getCollectTime()));
		}
		dbvpb.setReturnData(energyList);
		return dbvpb;
	}
	
	
	/**
	 * 获取不分页的
	 * @param map
	 * @return
	 */
	public  List<EnergyBean> getAllEnergyNoPage(Map map){
		return energyMapper.getAllEnergyDate(map);
	}

	public void setEnergyAction(Map map) {
		energyMapper.updateAction(map);
	}
	
	/**
	 * 仪表用量汇总
	* @date 2018年5月24日 上午8:56:12 
	* @author 李斌
	* @return List<EnergyBean> 
	* @throws
	 */  
	public DatatablesViewPageBean<EnergyBean> getEnergyRecordsSum(Map<String, Object> map) {
		DatatablesViewPageBean<EnergyBean> datatablesViewPageBean = new DatatablesViewPageBean<EnergyBean>();
		int count = energyMapper.getEnergyRecordsCount(map);
		datatablesViewPageBean.setiTotalDisplayRecords(count);
		datatablesViewPageBean.setiTotalRecords(count);
		datatablesViewPageBean.setReturnData(energyMapper.getEnergyRecordsSum(map));
		return datatablesViewPageBean;
	}

	/**
	 * 获取电表
	 * @param map
	 * @return
	 */
	public List<EnergyBean> getLeisureElectricEnergy(Map<String, Object> map) {
//		String prefix="E";  获取电表
		
		String company=map.get("loginCompany").toString();
		return energyMapper.getEnergyByNoPrefixAndState(1, null, company);
	}
	
	/**
	 * 获取水表
	 * @param map
	 * @return
	 */
	public List<EnergyBean> getLeisureFlowEnergy(Map<String, Object> map) {
//		String prefix="F"; 获取气表
		String company=map.get("loginCompany").toString();
		return energyMapper.getEnergyByNoPrefixAndState(3, null, company);
	}

	/**
	 * 设置仪表所属代表车间
	 * workShopIdArray 车间id字符串数组  json格式
	 * energyId 仪表id
	 * imgUrl 图片地址
	 * @param request
	 * @return
	 * @throws ServiceException
	 */
	public void setEnergyWorkshop(Map<String, Object> map) {
		StringUtil.checkIsTrue(map, "energyId", "未获取到仪表编号");
		StringUtil.checkNotNull(map, "imgUrl", "未获取到图片路径");
		StringUtil.checkIsTrue(map, "workShopIdArray", "未获取到车间编号");
		String workShopIdArray =map.get("workShopIdArray").toString();
		JSONArray jsonArray=JSONArray.fromObject(workShopIdArray);
		List<EnergyWorkShop> list=(List<EnergyWorkShop>) JSONArray.toCollection(jsonArray, EnergyWorkShop.class);
		String energyId=map.get("energyId").toString();
		int row=energyMapper.deleteEnergyWorkShopByEnergyId(energyId);
		if(list.size()>0) {
			Assert.isTrue(this.checkProcessIsUsed(energyId,list.get(0).getProcessId()),"工序被占用");
			int addRow=energyMapper.insertEnergyWorkShopByEnergy(energyId,list);
		}
		int updateRow=energyMapper.updateEnergByEergyId(map);
	}
	
	/**
	 * 校验工序是否被仪表使用
	 * @param energyNo
	 * @param processId
	 * @return
	 */
	private  boolean checkProcessIsUsed(String energyNo,String  processId) {
		boolean bool=true;
		List<String> useProcessEnergyNoList = energyMapper.getUseProcessEnergyNoList(energyNo,processId);
		if(useProcessEnergyNoList.size()>0) {
			bool=false;
		}
		return bool;
	}
	
	
	
	
	
	/**
	 * 获取车间能耗信息
	 * @param map
	 * @return
	 * @throws ParseException 
	 */
	public List<WorkEnergyConsumptionBean> getWorkEnergyConsumptionData(Map map) throws ParseException {
		String company=map.get("loginCompany").toString();
		String lossRedisKey=RedisKey.COMPANY_WORKSHOP_LOSS+company;
		SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM");
		String month=simpleDateFormat.format(new Date());
		map.put("month", month);
		//车间能耗
		List<WorkEnergyConsumptionBean> workEnergyConsumptionBeanList = (List<WorkEnergyConsumptionBean>) RedisCache.getDataFromRedis(lossRedisKey);
		if(null==workEnergyConsumptionBeanList) {
			workEnergyConsumptionBeanList=energyMapper.getWorkEnergyConsumptionData(map);
			if(null==workEnergyConsumptionBeanList) {
				workEnergyConsumptionBeanList=new ArrayList<WorkEnergyConsumptionBean>();
			}
			RedisCache.setDataToRedis(lossRedisKey, workEnergyConsumptionBeanList, RedisKey.COMPANY_WORKSHOP_LOSS_EXPIRETIME);
		}
		String capacityRedisKey=RedisKey.COMPANY_WORKSHOP_CAPACITY+company;
		List<ProductionExceptionBean> capacityList=(List<ProductionExceptionBean>) RedisCache.getDataFromRedis(capacityRedisKey);
		if(null==capacityList) {
			capacityList=workshopService.queryCapacity(map,RedisKey.QUERY_REPORT_CAPACITY);
			if(null==capacityList) {
				capacityList=new ArrayList<ProductionExceptionBean>();
			}
			RedisCache.setDataToRedis(capacityRedisKey, capacityList, RedisKey.COMPANY_WORKSHOP_CAPACITY_EXPIRETIME);
		}
		workEnergyConsumptionBeanList=this.megerCapacityAndLoss(workEnergyConsumptionBeanList,capacityList);
		return workEnergyConsumptionBeanList;
	}

	/**
	 * 合并产能和能耗数据
	 * @param workEnergyConsumptionBeanList 水电气信息
	 * @param capacityList  产能信息
	 * @return
	 */
	private List<WorkEnergyConsumptionBean> megerCapacityAndLoss(
			List<WorkEnergyConsumptionBean> workEnergyConsumptionBeanList, List<ProductionExceptionBean> capacityList) {
		for(WorkEnergyConsumptionBean workEnergyConsumptionBean:workEnergyConsumptionBeanList) {
			List<LossBean> lossList=workEnergyConsumptionBean.getDayList();
			//遍历车间
			for(ProductionExceptionBean productionExceptionBean:capacityList) {
				if(workEnergyConsumptionBean.getWorkShopId().equals(productionExceptionBean.getWorkShopId())) {
					List<DutyBean> workShopDuty=productionExceptionBean.getListDuty();
					if(null==workShopDuty) {
						break;
					}else {
						List<DutyBean> noHaveLossDutyList=null;
						//如果车间没有电气水损耗数据
						if(null!=lossList) {
							Set<String> lossDaySet=lossList.stream().map(LossBean::getDayTime).collect(Collectors.toSet());
							List<DutyBean> haveLossDutyList=workShopDuty.stream().filter(duty->lossDaySet.contains(duty.getDelayTime())).collect(Collectors.toList());
							noHaveLossDutyList=workShopDuty.stream().filter(duty->!lossDaySet.contains(duty.getDelayTime())).collect(Collectors.toList());
						    for(LossBean lossBean:lossList) {
						    	for(DutyBean dutyBean:haveLossDutyList) {
						    		if(dutyBean.getDelayTime().equals(lossBean.getDayTime())) {
						    			lossBean.setCapacity(dutyBean.getCapacity()+"");
						    			break;
						    		}
						    	}
						    }
						}else {
							noHaveLossDutyList=workShopDuty;
						}
						//给有产能没有能耗的天数赋值
						for(DutyBean dutyBean:noHaveLossDutyList) {
							LossBean lossBean=new LossBean();
							lossBean.setCapacity(dutyBean.getCapacity()+"");
							lossBean.setDayTime(dutyBean.getDelayTime());
							lossBean.setElectricUse("0");
							lossBean.setGasUse("0");
							lossBean.setWaterUse("0");
							lossList.add(lossBean);
						}
					}
					break;
				}
			}
		}
		return workEnergyConsumptionBeanList;
	}

	/**
	 * 获取仪表今天之前的使用情况
	 * 获取仪表年和月最大使用值（不含当天），和当月不含当天的使用量
	 * isUpdate  是否更新缓存   当有值（无论何值） 都更新缓存
	 * @param request
	 * @return
	 * @throws ServiceException
	 * @throws ParseException 
	 */
	@SuppressWarnings("unchecked")
	public List<EnergyBean>  getEnergyTodayBeforeDataFromRedis(Map<String, Object> map) {
		String company=map.get("loginCompany").toString();
		String redisKey=RedisKey.COMPANY_ENERGY_DISPLAY_VIEW+company;
		List<EnergyBean>  energyList= (List<EnergyBean>) RedisCache.getDataFromRedis(redisKey);
		//redis无值或者需要更新数据
//		if(null==energyList) {
		if(null==energyList || null != map.get("isUpdate")) {
			energyList=this.getEnergyTodayBeforeData(map);
			if(null==energyList) {
				energyList =new ArrayList<EnergyBean>();
			}
			SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String now=simpleDateFormat.format(new Date());
			simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd 23:59:59");
			String toDayLast=simpleDateFormat.format(new Date());
			double ss=TimeAndUnix.compareDate(now,toDayLast);
			//过期时间为当天晚上十二点
			RedisCache.setDataToRedis(redisKey, energyList, (int)(ss/1000)+"");
		}
		return energyList;
	}
	
	/**
	 * 获取仪表今天之前的使用情况
	 * 获取仪表年和月最大使用值（不含当天），和当月不含当天的使用量
	 * @param map
	 * @return
	 */
	public List<EnergyBean>  getEnergyTodayBeforeData(Map map) {
	   Map returnMap=new HashMap();
	   List<EnergyBean> energyBeans=energyMapper.getEnergyTodayBeforeData(map);
	   return energyBeans;	
	}

	/**
	 * 获取仪表今天的是使用情况
	 * @param map
	 * @return
	 */
	public List<EnergyBean> getEnergyTodayData(Map map) {
		return energyMapper.getEnergyTodayData(map);
	}

	/**
	 * 添加仪表
	 * jsonObject
	 * 仪表编号  no
	 * 仪表名称  name
	 * 仪表位置 address
	 * 变比（整数） variableRatio 变比（整数）
	 * 图片 imgUrl 
	 * 仪表类型 energyType  仪表类型   1 电表  2 水表  3气表 
	 * 仪表所属车间 workShopIdList workShopId isDefaultShow是否显示1 显示 0 不显示
	 */
	public String addEnergy(Map<String, Object> map) {
		StringUtil.checkIsTrue(map, "jsonObject", "未获取到参数");
		String jsonStr=map.get("jsonObject").toString();
		JSONObject  jsonObject=JSONObject.fromObject(jsonStr);
		String loginCompany = map.get("loginCompany").toString();
		jsonObject.put("company", map.get("loginCompany").toString());//赋值公司
		
		/**
		 * 如果不是注册到主服务器，还需要主服务器注册通过
		 * 因为读取数据需要在主服务器有备案
		 */
//		if(!mianUrl.equals(url)) {
//			String xx =WeiXinUtil.httpRequest("http://m86ncx.natappfree.cc/weixin/energy/addEnergyByOtherRequest?jsonStr="+jsonObject.toString());
//			if(!"SECCESS".equals(xx)) {
//				JSONObject errorObject = JSONObject.fromObject(xx);
//				String info = errorObject.getString("info");
//				Assert.isTrue(false,info);			
//			}
//		}
		
		Map classMap=new HashMap();
		classMap.put("workShopIdList", EnergyWorkShop.class);
		EnergyBean energyBean = (EnergyBean) JSONObject.toBean(jsonObject, EnergyBean.class, classMap);
		Assert.isTrue(null!=energyBean.getNo() && !"".equals(energyBean.getNo()),"未获取到仪表编号");
		map.remove("loginCompany");//所有公司仪表不可以相同
		map.put("no", energyBean.getNo());
		List<EnergyBean> list=this.getAllEnergyNoPage(map);
		map.put("loginCompany", loginCompany);
		Set<String> noSet=list.stream().map(EnergyBean::getNo).collect(Collectors.toSet());
		Assert.isTrue(!noSet.contains(energyBean.getNo()),"仪表编号已存在");
		if(energyBean.getEnergyType() == 1) {
			energyBean.setType(1);//是新型仪表
			try {
				materService.registerMater(energyBean.getNo());
				energyBean.setIsRegister(1);
			} catch (Exception e) {
				energyBean.setIsRegister(0);
			}
		}
		map.put("energyBean", energyBean);
		int row = energyMapper.addEnergy(map);
		Assert.isTrue(row>0,ReturnStringUtil.ADD_ERROR);
		if(null!=energyBean.getWorkShopIdList() && energyBean.getWorkShopIdList().size()>0) {
			Assert.isTrue(this.checkProcessIsUsed(energyBean.getNo(),energyBean.getWorkShopIdList().get(0).getProcessId()),"工序被占用");
			int addRow=energyMapper.insertEnergyWorkShopByEnergy(energyBean.getNo(),energyBean.getWorkShopIdList());
		}
		return ReturnStringUtil.ADD_SUCCESS;
	}
	
	/**
	 * 获取
	 * @param jsonStr
	 * @return
	 */
	public String addEnergyByOtherRequest(String jsonStr) {
		JSONObject  jsonObject=JSONObject.fromObject(jsonStr);
		EnergyBean energyBean = (EnergyBean) JSONObject.toBean(jsonObject, EnergyBean.class);
		Assert.isTrue(null!=energyBean.getNo() && !"".equals(energyBean.getNo()),"未获取到仪表编号");
        Map map=new HashMap();
		map.put("no", energyBean.getNo());
		List<EnergyBean> list=this.getAllEnergyNoPage(map);
		Set<String> noSet=list.stream().map(EnergyBean::getNo).collect(Collectors.toSet());
		Assert.isTrue(!noSet.contains(energyBean.getNo()),"仪表编号已存在");
		if(energyBean.getEnergyType() == 1) {
			energyBean.setType(1);//是新型仪表
			try {
				materService.registerMater(energyBean.getNo());
				energyBean.setIsRegister(1);
			} catch (Exception e) {
				energyBean.setIsRegister(0);
			}
		}
		map.put("energyBean", energyBean);
		int row = energyMapper.addEnergy(map);
		Assert.isTrue(row>0,ReturnStringUtil.ADD_ERROR);
		return "SUCCESS";
	}
	
	
	
	
	
	

	/**
	 * 获取仪表能耗信息
	 * @param map
	 * @return
	 */
	public List<EnergyBean> materConsumption(Map<String, Object> map) {
		List<EnergyBean> list= energyMapper.materConsumption(map);//获取能耗信息
		return list;
	}

	/**
	 * jsonArray
	 * no  仪表编号
	 * isAgree 是否同意使用  1 同意 2 不同意
	 * 设置电表是否可用
	 * @param map
	 * @return
	 */
	public String setEnergyIsCanUsed(Map<String, Object> map) {
		StringUtil.checkIsTrue(map, "jsonArray", "未获取到参数");
		String jsonStr = map.get("jsonArray").toString();
		JSONArray jsonArray= JSONArray.fromObject(jsonStr);
		List<EnergyBean> list = (List<EnergyBean>) JSONArray.toCollection(jsonArray, EnergyBean.class);
		int  row = energyMapper.setEnergyIsCanUsed(list);
		return ReturnStringUtil.SET_SUCCESS;
	}

	
	
	/**
	 * 远程获取仪表数据
	 * @return
	 */
	public String testReadEnergy() {
		//先获取本机所有表号
	    List<EnergyBean> energyList=null;
		//向服务器请求数据
	    List<String> noList=energyList.stream().map(EnergyBean::getNo).collect(Collectors.toList());
	    JSONArray jsonArray = JSONArray.fromObject(noList);
	    String xx =WeiXinUtil.httpRequest("http://m86ncx.natappfree.cc/weixin/energy/addEnergyByOtherRequest?jsonStr="+jsonArray.toString());
	    JSONArray returnArray = JSONArray.fromObject(xx);
	    List<EnergyBean> returnList= (List<EnergyBean>) JSONArray.toCollection(returnArray, EnergyBean.class);
//	    if(!"SECCESS".equals(xx)) {
//			JSONObject errorObject = JSONObject.fromObject(xx);
//			String info = errorObject.getString("info");
//            Assert.isTrue(false,info);			
//		}
	    //保存数据
	    if(returnList.size() > 0 ) {
	    	int  row = energyMapper.setDegeeByOtherHost(returnList);
	    	
	    }
		return "SUCCESS";
	}
	
	
	/**
	 * 给请求电表返回数据
	 */
	public String returnEnergyData(String jsonStr) {
		JSONArray jsonArray = JSONArray.fromObject(jsonStr);
		List<String> idList=jsonArray.subList(0, jsonArray.size());
		/**
		 * 从redis中获取
		 */
		List<EnergyBean> returnList=new ArrayList<EnergyBean>();
		List<EnergyBean> allEnergyList=(List<EnergyBean>) RedisCache.getDataFromRedis("");
		if(allEnergyList.size()>0) {
			returnList = allEnergyList.stream().filter(pp->idList.contains(pp.getNo())).collect(Collectors.toList());
		}
		JSONArray returnArray=JSONArray.fromObject(returnList);
		return returnArray.toString();
	}
	
	static{
        try {
//            用流读入properties配置文件
            InputStream inputStream = EnergyService.class.getClassLoader().getResourceAsStream("db.properties");
            Properties properties = new Properties();
//            从输入字节流读取属性列表（键和元素对）
            properties.load(inputStream);
//            用此属性列表中指定的键搜索属性，获取驱动，url，username，password
            url = properties.getProperty("datasource.url");
            System.out.println(url);
//            加载驱动
//            Class.forName(dirverName);
        } catch (IOException e) {
            e.printStackTrace();
     }
	}

	/**
	 * 校验仪表是否有过记录
	 * @param map
	 * @return
	 */
	public Boolean checkEnergyIsUsed(Map<String, Object> map) {
		Boolean boolean1= false;
		String energyId = energyMapper.checkEnergyIsUsed(map);
		if(energyId == null || "".equals(energyId)) {
			boolean1 = true;
		}
		return boolean1;
	}
}
